package com.mingqijia.gassafety.console.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gap.basic.base.CommonResponse;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.entity.redis.LatestLog;
import com.mingqijia.gassafety.db.entity.vo.DeviceStateVO;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.constant.OperateRecordEnum;
import com.mingqijia.gassafety.shared.log.LogRecord;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.feign.ConsoleSkFeignClient;
import com.mingqijia.gassafety.webserver.request.LatestLogListRequest;
import com.mingqijia.gassafety.webserver.request.UpdateDeviceStateRequest;
import com.mingqijia.gassafety.webserver.request.UpdateListShowRequest;
import com.mingqijia.gassafety.webserver.request.inner.LatestSummaryRequest;
import com.mingqijia.gassafety.webserver.response.*;
import com.mingqijia.gassafety.webserver.response.client.ConcentrationCurveRes;
import com.mingqijia.gassafety.webserver.response.sk.AlarmSupplierListVo;
import com.mingqijia.gassafety.webserver.response.sk.ConsoleSkSupplierListResponse;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.service.cmp.EquipmentCmpService;
import com.mingqijia.gassafety.webserver.service.workorder.DtuBindingOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.Constants.ORG_MAP_SUBSCODE;
import static com.mingqijia.gassafety.webserver.constant.DeviceConstant.*;

/**
 * <p>
 * 实时状态
 *
 * @author guoliang.lao
 * @since 2022-02-18
 */

@Slf4j
@Api(tags = "实时监测")
@RestController(value = "LatestLogController")
@RequestMapping("/business/v1/latest/log")
public class LatestLogController {
    @Autowired
    EquipmentService equipmentService;
    @Autowired
    LatestLogService latestLogService;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    ContactsService contactsService;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    HistoryLogService historyLogService;
    @Autowired
    DtuBindingOrderService dtuBindingOrderService;
    @Autowired
    ReceiverValveService receiverValveService;
    @Autowired
    OrganizationService organizationService;
    @Autowired
    ValveInfoService valveInfoService;
    @Autowired
    DeviceStateService deviceStateService;
    @Autowired
    CompanyService companyService;

    @Autowired
    ConsoleSkFeignClient consoleSkFeignClient;
    @Autowired
    private EquipmentCmpService equipmentCmpService;

    @Autowired
    private ConsumerLocationService consumerLocationService;

    @ApiOperation("查询实时状态列表")
    @RequestMapping(value = "list", method = RequestMethod.POST)
    public CommonResponse<PageUtil<LatestLogListResponse>> list(@RequestBody LatestLogListRequest request){
        return CommonResponse.success(latestLogService.getList(request));
    }

    @ApiOperation("查询实时状态数量")
    @RequestMapping(value = "summary", method = RequestMethod.POST)
    public CommonResponse<LatestSummaryResponse> summary(){
        return CommonResponse.success(latestLogService.getSummary(new LatestSummaryRequest()));
    }

    @ApiOperation("实时状态详情")
    @RequestMapping(value = "detail", method = RequestMethod.GET)
    public CommonResponse<LatestLogDetailResponse> detail(@RequestParam @ApiParam(value = "设备号") String iMEI){
        LatestLogDetailResponse res = new LatestLogDetailResponse();
        String spId = ApplicationUtils.getWorkingSpId();
        //所属组织
        List<String> spIds = organizationService.getSpIds(spId);
        //设备基础信息
        LambdaQueryWrapper<Dtu> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.in(Dtu::getSpId,spIds).eq(Dtu::getIMEI,iMEI).eq(Dtu::getIsDeleted, Constants.IS_DELETED_FALSE);
        Dtu equipment = equipmentService.getOne(queryWrapper);
        if (equipment == null) {
            return CommonResponse.failure("设备不存在");
        }
        //设备是否有电磁阀
        res.setHasValve(equipment.getValveInfoId() == 0 ? "-":"有");
        if (equipment.getValveInfoId() != 0){
            ValveInfo info = valveInfoService.getInfoById(equipment.getValveInfoId());
            BeanUtils.copyProperties(info, res);
        }

        BeanUtils.copyProperties(equipment,res);
        //查询组织架构名称
        List<CompanyResponse> companyNameList = companyService.queryCompanyNameList(spIds);
        Map<String, String> companyNameMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(companyNameList)) {
            companyNameMap = companyNameList.stream().collect(Collectors.toMap(CompanyResponse::getSpId, CompanyResponse::getName));
        }

        res.setImei(equipment.getIMEI());
        res.setEquipmentName(equipment.getName());
        //紫荆设备的接收器、电磁阀信息
        if ( equipment.getEquipmentFrom() == Constants.ZJ_EQUIPMENT_FROM) {
            LambdaQueryWrapper<ReceiverValve> lqw = new LambdaQueryWrapper<>();
            lqw.eq(ReceiverValve::getDeviceId, equipment.getIMEI()).in(ReceiverValve::getSpId, spIds)
                    .eq(ReceiverValve::getIsDeleted, Constants.IS_DELETED_FALSE);
            ReceiverValve receiverValve = receiverValveService.getOne(lqw);
            String valveWorkingInfo = "";
            String receiverWorkingInfo = "";
            if (receiverValve != null) {
                res.setReceiverCode(receiverValve.getReceiverCode());
                res.setReceiverType(receiverValve.getReceiverType());
                res.setReceiverPowerMode(receiverValve.getReceiverPowerMode());
                res.setOnlineCode(equipment.getOnlineCode());
                res.setValveId(receiverValve.getValveId());
                res.setWithReceiver(true);

                //电磁阀工作信息
                if (VALVE_STATUS_OPEN == receiverValve.getValveStatus()) {
                    valveWorkingInfo = VALVE_STATUS_OPEN_INFO;
                } else if (VALVE_STATUS_CLOSE == receiverValve.getValveStatus()) {
                    valveWorkingInfo = VALVE_STATUS_CLOSE_INFO;
                }
                if (VALVE_WORK_STATUS_NORMAL == receiverValve.getBrokenStatus()) {
                    valveWorkingInfo += "(" + VALVE_WORK_STATUS_NORMAL_INFO + ")";
                } else if (VALVE_WORK_STATUS_BROKEN == receiverValve.getBrokenStatus()) {
                    valveWorkingInfo += "(" + receiverValve.getBrokenStatusInfo() + ")";
                }
                res.setValveWorkingInfo(valveWorkingInfo);

                //接受器工作信息
                if (RECEIVER_STATUS_OFFLINE == receiverValve.getReceiverStatus()){
                    receiverWorkingInfo = RECEIVER_STATUS_OFFLINE_INFO;
                }else if (RECEIVER_STATUS_NORMAL == receiverValve.getReceiverStatus()){
                    receiverWorkingInfo = RECEIVER_STATUS_NORMAL_INFO;
                }
                if (BATTERY_STATUS_NORMAL == receiverValve.getBatteryStatus()){
                    receiverWorkingInfo += "(" + BATTERY_STATUS_NORMAL_INFO + ")";
                }else if (BATTERY_STATUS_BROKEN == receiverValve.getBatteryStatus()){
                    receiverWorkingInfo += "(" + BATTERY_STATUS_BROKEN_INFO + ")";
                }
                res.setReceiverWorkingInfo(receiverWorkingInfo);
            }else{
                res.setWithReceiver(false);
            }
        }
        //设备厂商名称
        ConsoleSkSupplierListResponse response = equipmentCmpService.supplierListRequest();
        List<AlarmSupplierListVo> supplierListVos = new ArrayList<>();
        if (response != null && response.getCode() == 0 && response.getData() != null && org.apache.commons.collections.CollectionUtils.isNotEmpty(response.getData())) {
            supplierListVos = response.getData();
        }
        try{
            //设备类型
            if (!StringUtils.isEmpty(res.getEquipmentType())) {

                DictionaryItemRespDTO equipmentTypeDict = holder.getDictionaryByKey(
                        EquipmentType.DICT_CODE).stream().filter(a->a.getValue().equals(
                        res.getEquipmentType())).collect(Collectors.toList()).get(0);
                res.setEquipmentTypeName(equipmentTypeDict.getName());
            }
            //运营商
            if (!StringUtils.isEmpty(res.getOperators())) {
                DictionaryItemRespDTO operatorsDict = holder.getDictionaryByKey(
                        Constants.OPERATOR_CODE).stream().filter(a->a.getValue().equals(
                        equipment.getOperators())).collect(Collectors.toList()).get(0);
                res.setOperators(operatorsDict.getName());
            }
            //设备厂商
            if (!StringUtils.isEmpty(res.getEquipmentManufacturer())) {
                List<AlarmSupplierListVo> listVos = supplierListVos.stream().filter(a -> a.getAlarmSystemCode().equals(
                        res.getEquipmentManufacturer())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(listVos)) {
                    res.setEquipmentManufacturer(listVos.get(0).getMsName());
                }
            }
            //通讯方式
            if (!StringUtils.isEmpty(res.getCommunicationMode())) {
                DictionaryItemRespDTO communicationModeDict = holder.getDictionaryByKey(
                        Constants.COMMUNICATION_Mode_CODE).stream().filter(a->a.getValue().equals(
                        equipment.getCommunicationMode())).collect(Collectors.toList()).get(0);
                res.setCommunicationMode(communicationModeDict.getName());
            }

            //检测类型
            if (!StringUtils.isEmpty(res.getDetectionType())) {
                String detectionType = "";
                String[] detectionTypes = equipment.getDetectionType().split(";");
                for (String s : detectionTypes) {
                    DictionaryItemRespDTO detectionTypeDict = holder.getDictionaryByKey(
                            Constants.DETECTION_TYPE_CODE).stream().filter(a->a.getValue().equals(
                            s)).collect(Collectors.toList()).get(0);
                    detectionType = detectionType + detectionTypeDict.getName() + ";";
                }
                res.setDetectionType(detectionType);
            }
        } catch (Exception e) {
            log.error("字典匹配失败",e);
        }

        //实时信息
        LatestLog latestLog = latestLogService.get(equipment.getIMEI(),equipment.getSpId());
        if (latestLog != null) {
            BeanUtils.copyProperties(latestLog,res);
            res.setLatestTime(latestLog.getLatestTime());
            res.setBtV(latestLog.getBtV());
        }

        //关联控制器信息
        if (equipment.getEquipmentType().equals(EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode())) {
            LambdaQueryWrapper<Dtu> queryControllerWrapper = new LambdaQueryWrapper();
            queryControllerWrapper.eq(Dtu::getIsDeleted,0).in(Dtu::getSpId,spIds);
            queryControllerWrapper.eq(Dtu::getIMEI,org.apache.commons.lang.StringUtils.substringBefore(iMEI, "-"));
            Dtu controller = equipmentService.getOne(queryControllerWrapper);
            if (controller != null) {
                //其控制时是否有电磁阀
                res.getGasController().setHasValve(equipment.getValveInfoId() == 0 ? "-":"有");
                if (equipment.getValveInfoId() != 0){
                    ValveInfo info = valveInfoService.getById(equipment.getValveInfoId());
                    res.getGasController().setValveName(info.getValveName());
                    res.getGasController().setValveManufacturer(info.getValveManufacturer());
                    res.getGasController().setValveModel(info.getValveModel());
                    res.getGasController().setValveMaterial(info.getValveMaterial());
                    res.getGasController().setValveValidity(info.getValveValidity());
                }
                BeanUtils.copyProperties(controller,res.getGasController());
                res.getGasController().setEquipmentName(controller.getName());
                res.getGasController().setLatestTime(res.getLatestTime());
                res.getGasController().setSignal(res.getSignal());
                res.getGasController().setInstallationAddress(controller.getInstallationAddress());
                res.getGasController().setPositionLat(controller.getPositionLat());
                res.getGasController().setPositionLon(controller.getPositionLon());
                //redis实时信息
                LatestLog latestLog2 = latestLogService.get(equipment.getIMEI(),equipment.getSpId());
                if (latestLog != null) {
                    res.getGasController().setBtV(latestLog2.getBtV());
                    res.getGasController().setEquipmentStatus(latestLog2.getEquipmentStatus());
                }
                try{
                    //设备厂商
                    if (!StringUtils.isEmpty(controller.getEquipmentManufacturer())) {
//                        DictionaryItemRespDTO manufacturerDict = holder.getDictionaryByKey(
//                                Constants.MANUFACTURER_CODE).stream().filter(a->a.getValue().equals(
//                                controller.getEquipmentManufacturer())).collect(Collectors.toList()).get(0);
                        List<AlarmSupplierListVo> listVos = supplierListVos.stream().filter(a -> a.getAlarmSystemCode().equals(
                                res.getEquipmentManufacturer())).collect(Collectors.toList());
                        if (!CollectionUtils.isEmpty(listVos)) {
                            res.getGasController().setEquipmentManufacturer(listVos.get(0).getMsName());
                        }
                    }
                    //设备类型
                    if (!StringUtils.isEmpty(controller.getEquipmentType())) {
                        DictionaryItemRespDTO equipmentTypeDict = holder.getDictionaryByKey(
                                EquipmentType.DICT_CODE).stream().filter(a->a.getValue().equals(
                                controller.getEquipmentType())).collect(Collectors.toList()).get(0);
                        res.getGasController().setEquipmentTypeName(equipmentTypeDict.getName());
                    }
                    //运营商
                    if (!StringUtils.isEmpty(controller.getOperators())) {
                        DictionaryItemRespDTO operatorsDict = holder.getDictionaryByKey(
                                Constants.OPERATOR_CODE).stream().filter(a->a.getValue().equals(
                                controller.getOperators())).collect(Collectors.toList()).get(0);
                        res.getGasController().setOperators(operatorsDict.getName());
                    }
                    //通讯方式
                    if (!StringUtils.isEmpty(controller.getCommunicationMode())) {
                        DictionaryItemRespDTO communicationModeDict = holder.getDictionaryByKey(
                                Constants.COMMUNICATION_Mode_CODE).stream().filter(a->a.getValue().equals(
                                controller.getCommunicationMode())).collect(Collectors.toList()).get(0);
                        res.getGasController().setCommunicationMode(communicationModeDict.getName());
                    }
                } catch (Exception e) {
                    log.error("字典匹配失败",e);
                }
            }
        }
        //客户信息
        List<Integer> consumerIdList = new ArrayList();
        consumerIdList.add(equipment.getConsumerId());
        LambdaQueryWrapper<Consumer> consumerQueryWrapper = new LambdaQueryWrapper<>();
        consumerQueryWrapper.in(Consumer::getSpId,spIds).in(Consumer::getId,consumerIdList).eq(Consumer::getIsDeleted, Constants.IS_DELETED_FALSE);
        List<Consumer> consumerList = consumerService.list(consumerQueryWrapper);
        Consumer consumer = new Consumer();
        if (!CollectionUtils.isEmpty(consumerList)) {
            consumer = consumerList.get(0);
            if (equipment.getConsumerId().equals(consumer.getId())) {
                res.setSubsCode(consumer.getSubsCode());
                res.setIndustryType(consumer.getIndustryType());
                res.setCustName(consumer.getCustName());
                res.setCustAddress(consumer.getCustAddress());
                res.setCustPhone(consumer.getCustPhone());
                res.setCustomerAddress(consumer.getCustomerAddress());
                try {
                    //行业类型
                    if (!StringUtils.isEmpty(res.getIndustryType())) {
                        DictionaryItemRespDTO communicationModeDict = holder.getDictionaryByKey(
                                Constants.INDUSTRY_TYPE_CODE).stream().filter(a->a.getValue().equals(
                                res.getIndustryType())).collect(Collectors.toList()).get(0);
                        res.setIndustryTypeName(communicationModeDict.getName());
                    }
                } catch (Exception e) {
                    log.error("字典匹配失败",e);
                }
                res.setCustStatus(consumer.getCustStatus());
                res.setCustType(consumer.getCustType());
                res.setConsumerName(consumer.getName());
                res.setRemark(consumer.getRemark());
                res.setUpdateTime(consumer.getUpdatedAt());
                res.setMemberId(consumer.getMemberId());
                res.setMemberPhone(consumer.getPhone());
                res.setConsumerId(consumer.getId());
                res.setVerificationTime(consumer.getVerificationTime());
                //获取服务区数据
                Map<Integer, ConsumerFuncAreaResponse> consumerFuncAreaMap = consumerLocationService.getConsumerFuncArea(
                        Arrays.asList(consumer.getId()),
                        spId,
                        null
                );
                if( null!=consumerFuncAreaMap && consumerFuncAreaMap.containsKey(consumer.getId())){
                    res.setFuncArea(consumerFuncAreaMap.get(consumer.getId()));
                }
            }
            //批量查询字典
            List<DictionaryItemRespDTO> orgMapSubsCodeList = holder.getDictionaryByKey(ORG_MAP_SUBSCODE);
            Map<String, String> orgSubsCodeMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(orgMapSubsCodeList)) {
                orgSubsCodeMap = orgMapSubsCodeList.stream().collect(Collectors.toMap(DictionaryItemRespDTO::getDescription, DictionaryItemRespDTO::getCompanyName));
            }
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(consumer.getOrgCode()) && orgSubsCodeMap.containsKey(consumer.getOrgCode())) {
                res.setCompanyName(orgSubsCodeMap.get(consumer.getOrgCode()));
            } else {
                if (companyNameMap.containsKey(consumer.getSpId())) {
                    res.setCompanyName(companyNameMap.get(consumer.getSpId()));
                }
            }
        }
        //客户联系人信息
        List<Map<String, Object>> contactList = contactsService.selectInfo(equipment.getConsumerId().toString());
        for (Map<String, Object>  map : contactList) {
            LatestLogDetailResponse.Contact contact = new LatestLogDetailResponse.Contact();
            contact.setContactName(map.get("name").toString());
            contact.setTelephone(map.get("telephone").toString());
            contact.setLevel(Integer.valueOf(map.get("level").toString()));
            if (contact.getLevel() != null) {
                DictionaryItemRespDTO communicationModeDict = holder.getDictionaryByKey(
                        Constants.CONTACT_LEVEL).stream().filter(a->a.getValue().equals(
                        contact.getLevel().toString())).collect(Collectors.toList()).get(0);
                contact.setLevelName(communicationModeDict.getName());
            }
            contact.setRemark(map.get("remark").toString());
            res.getContactList().add(contact);
        }
        //安装订单信息
        QueryWrapper<DtuBindingOrder> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(DtuBindingOrder::getDeviceId, equipment.getId())
                .eq(DtuBindingOrder::getConsumerId,consumer.getId())
                .eq(DtuBindingOrder::getIsDeleted, false);
        DtuBindingOrder bindingOrder = dtuBindingOrderService.getOne(wrapper);
        if (bindingOrder != null) {
            res.setContactName(bindingOrder.getCustName());
            res.setContactPhone(bindingOrder.getPhone());
            res.setContactAddress(bindingOrder.getAddress());
        }
        //查询控制器的点位数
        if (equipment.getEquipmentType().equals(EquipmentType.GAS_ALARM_CONTROLLER.getCode())) {
            LambdaQueryWrapper<Dtu> pointWrapper = new LambdaQueryWrapper();
            pointWrapper.in(Dtu::getSpId,spIds).likeRight(Dtu::getIMEI,iMEI).eq(Dtu::getIsDeleted,0);
            List<Dtu> pointList = equipmentService.list(pointWrapper);
            //去除控制器，剩余点位数
            res.setPoint(pointList.size()-1);
            for (Dtu dtu : pointList) {
                if (!dtu.getEquipmentType().equals(EquipmentType.GAS_ALARM_CONTROLLER.getCode())) {
                    LatestLogDetailResponse.Equipment point = new LatestLogDetailResponse.Equipment();
                    point.setImei(dtu.getIMEI());
                    point.setEquipmentName(dtu.getName());
                    point.setInstallationPosition(dtu.getInstallationPosition());
                    LatestLog pointLatestLog = latestLogService.get(dtu.getIMEI(),dtu.getSpId());
                    if (latestLog != null) {
                        BeanUtils.copyProperties(pointLatestLog,point);
                        point.setXlel(pointLatestLog.getXlel());
                    }
                    if (dtu.getValveInfoId() != 0){
                        ValveInfo info = valveInfoService.getInfoById(equipment.getValveInfoId());
                        BeanUtils.copyProperties(info, point);
                    }
                    res.getEquipmentList().add(point);
                }
            }
        }
        return CommonResponse.success(res);
    }


    @ApiOperation( value = "客户最新运行状态")
    @GetMapping("/GetAllConsumerStatuses")
    public CommonResponse<List<ConsumerStatusResponse>> consumerStatus(){
        List<ConsumerStatusResponse> list = equipmentService.consumerStatus();
        return  CommonResponse.success( list );

    }

    @ApiOperation("报警浓度曲线")
    @RequestMapping(value = "historyLog", method = RequestMethod.GET)
    public CommonResponse<List<ConcentrationCurveRes>> historyLog(@RequestParam @ApiParam(value = "设备号") String imei,
                                                                  @RequestParam @ApiParam(value = "开始时间") String timeStart,
                                                                  @RequestParam @ApiParam(value = "结束时间") String timeEnd){
        if (StringUtils.isEmpty(imei)) return CommonResponse.failure("设备号不能为空！");
        if (StringUtils.isEmpty(timeStart)) return CommonResponse.failure("开始时间不能为空！");
        if (StringUtils.isEmpty(timeEnd)) return CommonResponse.failure("结束时间不能为空！");
        return CommonResponse.success(historyLogService.getConcentrationCurve(imei,timeStart,timeEnd));
    }

    @LogRecord(operateType = OperateRecordEnum.OPERATE_TYPE_56, detail = "'【设备号：' + #request.imei + '】\n状态：由【' + #request.predeviceState + '】变更成【' + #request.deviceState +'】'", commonInfo = "#request.imei")
    @PostMapping("/updateDeviceState")
    @ApiOperation(value = "设备状态调整")
    public CommonResponse<Object> updateDeviceState(@RequestBody UpdateDeviceStateRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        int deviceState = deviceStateService.updateDeviceState(request, spId);
        return CommonResponse.success(deviceState);
    }
}

